今天的話,我們來討論一下tf.keras
的api。首先,今天要討論的tf.keras
與我們所熟知的keras是不太一樣的,以前我們所使用的keras,他的backend其實也是用tensorflow,且Keras有自己做好的模型wrapper。而現在TF2.0 大力將keras整進去,因此今天討論的會是TF2.0下的tf.keras。一般來說,在tf.keras下,比較常使用的像是 tf.keras.layer
, tf.keras.losses
,tf.keras.mertrics
, tf.keras.optimzer
等等。接下來,會挑幾個重要或者常用的來說明
tf.keras.metrics:
主要像是用在training model的過程,常會用以紀錄像是loss或者accuracy等等的模型數值。
假如要建立一些模型衡量指標就可以使用像是:
Model_acc = tf.keras.metrics.Accurcy()
#or
Model_mean = tf.keras.metrics.Mean()
接下來當我們要update或者說增加裡面的數值就會使用像是:
Model_acc.update_state(y,pred)
#or
Model_mean.update_state(current_loss)
之後就可以在模型裡面print出這些數值
#training steps
print(step,'Train_loss:',Model_mean.result().numpy(),'Train_Acc',Model_acc.result().numpy())
最後當每個epoch跑完要清楚裡面的數值時,可以使用像是
Model_mean.reset_states()
Model_acc.reset_states()
2.Model Define:
在Model定義裡像是我們會使用tf.keras.Sequential
來包網路架構,在各層的定義就會使用tf.keras.layers
來定義每一層 (Ex: neuron數、activation function等等)。最後就丟進去compile即可!
model = tf.keras.Sequential([
tf.keras.layers.Dense(256,activation=tf.nn.relu),
tf.keras.layers.Dense(128,activation=tf.nn.relu),
tf.keras.layers.Dense(64,activation=tf.nn.relu),
tf.keras.layers.Dense(32,activation=tf.nn.relu),
tf.keras.layers.Dense(16,activation=tf.nn.relu),
tf.keras.layers.Dense(10,activation=tf.nn.relu)
])
model.build(input_shpae=[-1,28*28])
model.trainable_variables
就可以拿取model中要train的variable (Ex: weight , bias等)。
假如想要custom layer,也是可以的!在class中主要就是要實現init、call跟build的方法,然後記得 要繼承tf.keras.layer。
init : 主要就是初始化,以及繼承
call:執行向前傳導
build: 輸入shape,定義viarble的等等
範例如下:
class MyDenseLayer(tf.keras.layers.Layer):
def __init__(self, num_outputs):
super(MyDenseLayer, self).__init__()
self.num_outputs = num_outputs
def build(self, input_shape):
self.kernel = self.add_variable("kernel",
shape=[int(input_shape[-1]),
self.num_outputs])
def call(self, input):
return tf.matmul(input, self.kernel)
layer = MyDenseLayer(10)
print(layer(tf.zeros([10, 5])))
print(layer.trainable_variables)
而自定義一個網路架構也是非常類似的,但他所繼承的類別就是tf.keras.Model
Ex:
class ResnetIdentityBlock(tf.keras.Model):
def __init__(self, kernel_size, filters):
super(ResnetIdentityBlock, self).__init__(name='')
filters1, filters2, filters3 = filters
self.conv2a = tf.keras.layers.Conv2D(filters1, (1, 1))
self.bn2a = tf.keras.layers.BatchNormalization()
self.conv2b = tf.keras.layers.Conv2D(filters2, kernel_size, padding='same')
self.bn2b = tf.keras.layers.BatchNormalization()
self.conv2c = tf.keras.layers.Conv2D(filters3, (1, 1))
self.bn2c = tf.keras.layers.BatchNormalization()
def call(self, input_tensor, training=False):
x = self.conv2a(input_tensor)
x = self.bn2a(x, training=training)
x = tf.nn.relu(x)
x = self.conv2b(x)
x = self.bn2b(x, training=training)
x = tf.nn.relu(x)
x = self.conv2c(x)
x = self.bn2c(x, training=training)
x += input_tensor
return tf.nn.relu(x)
block = ResnetIdentityBlock(1, [1, 2, 3])
print(block(tf.zeros([1, 2, 3, 3])))
print([x.name for x in block.variables])
tf.GradientTape()
來訓練參數。但若是在tf.keras裡面就超級方便!就像我們第一個最間單的Lab,直接下:model.compile(optimizer='adam',
loss='mean_squared_error',
metrics=['mean_squared_error'])
history = model.fit(X_train.values ,y_train.values, epochs=100, validation_split = 0.1)
model.evaluate(X_val)
#Save weight
model.save_weights('weights.ckpt')
#Load weight
model = create_model()
model.load_weights('weights.ckpt')
# save model
model.save('model.h5')
# load model
model = tf.keras.models.load_model('model.h5')
今天討論完tf.keras的api,是不是覺得真的很方便XD,就跟下面的梗圖一樣。感謝大家漫長的閱讀~乾蝦!
您好,我想請問:若我想在Convolution layer前對tensor的每一elements做取二進位16bits的運算(轉成二進位後取整數10bits+小數6bits再轉成十進位),我可以將此function轉成keras layer再放到model做training嗎?謝謝您!